/**
 * Patient class handles patient information 
 */
package docoffice.doss;
import java.util.logging.Logger;
import java.sql.ResultSet;

import docoffice.database.DatabaseManager;


/**
 * @author Ray Nosari
 * @version $Revision: 1.0 $
 */
public class Patient extends User{
	
	/**
	 * Fields name, address, phone, email, gender, age, insuranceCarrier, allergies[]
	 */
	private String name, address, phone, email, gender, allergies;
	
	/**
	 * Field insurance.
	 */
	private insuranceCarrier insurance;
	
	/**
	 * Field age.
	 */
	private int age, id;
	
	/**
	 * Field LOG.
	 */
	private static final Logger LOG = Logger.getLogger("Patient");
	
	/**
	 * Patient constructor
	 * @param name
	 */
	public Patient(String name){
		this.name = name;
		this.setUserType("Patient");
	}
	
	/**
	 * Overloaded Patient constructor
	 * @param name
	 * @param insuranceCarrier
	 */
	public Patient(String name, insuranceCarrier insurance){
		this.name = name;
		this.insurance = insurance;
		this.setUserType("Patient");
	}
	
	/**
	 * Overloaded Patient constructor
	 * @param name
	 * @param gender
	 * @param age
	 */
	public Patient(String name, String gender, int age){
		this.name = name;
		this.gender = gender;
		this.age = age;
		this.setUserType("Patient");
	}
	
	/**
	 * Overloaded Patient constructor
	 * @param name
	 * @param address
	 * @param gender
	 * @param age
	 * @param insuranceCarrier
	 */
	public Patient(String name, String address, String gender, int age, 
			insuranceCarrier insurance){
		this.name = name;
		this.address = address;
		this.gender = gender;
		this.age = age;
		this.insurance = insurance;
		this.setUserType("Patient");
	}
	
	/**
	 * getter for name
	
	 * @return name */
	public String getName(){
		return name;
	}
	
	/**
	 * setter for name
	 * @param name
	 */
	public void setName(String name){
		this.name = name;
	}
	
	/**
	 * getter for address
	 * @return String */
	public String getAddress(){
		return address;
	}
	
	/**
	 * setter for address
	 * @param address
	 */
	public void setAddress(String address){
		this.address = address;
	}
	
	/**
	 * getter for phone
	 * @return String */
	public String getPhone(){
		return phone;
	}
	
	/**
	 * setter for phone
	 * @param phone
	 */
	public void setPhone(String phone){
		this.phone = phone;
	}
	
	/**
	 * getter for email
	 * @return String */
	public String getEmail(){
		return email;
	}
	
	/**
	 * setter for email
	 * @param email
	 */
	public void setEmail(String email){
		this.email = email;
	}
	
	/**
	 * getter for gender
	 * @return String */
	public String getGender(){
		return gender;
	}
	
	/**
	 * setter for gender
	 * @param gender
	 */
	public void setGender(String gender){
		this.gender = gender;
	}
	
	/**
	 * getter for age
	 * @return int */
	public int getAge(){
		return age;
	}
	
	/**
	 * setter for age
	 * @param age
	 */
	public void setAge(int age){
		this.age = age;
	}
	
	/**
	 * getter for id
	
	 * @return id */
	public int getId(){
		return this.id;
	}
	
	/**
	 * setter for id
	 * @param id
	 */
	public void setId(int id){
		this.id = id;
	}
	
	/**
	 * getter for insuranceCarrier
	 * @return String */
	public insuranceCarrier getInsuranceCarrier(){
		return insurance;
	}
	
	/**
	 * setter for insuranceCarrier
	 * @param insuranceCarrier
	 */
	public void setInsuranceCarrier(insuranceCarrier insurance){
		this.insurance = insurance;
	}
	
	/**
	 * getter for allergies
	 * @return String[] */
	public String getAllergies(){
		return allergies;
	}
	
	/**
	 * setter for allergies
	 * @param allergies
	 */
	public void setAllergies(String allergies){
		this.allergies = allergies;
	}
	
	/**
	 * overloaded toString method
	
	 * @return String */
	public String toString(){
		final String ret = "Patient class contains information about Patients";
		return ret;
	}
	
	/**
	 * createUser overload
	 * @param username String
	 * @param name String
	 * @param address String
	 * @param gender String
	 * @param age int
	 * @param insurance String
	 */
	public void createPatient(){
		final String username = this.getUsername();
		final insuranceCarrier carrier = this.insurance;
		final String insurance = carrier.toString();
		final DatabaseManager dbMgr = new DatabaseManager();
		final String sqlQuery = "INSERT INTO patient (Username, PatientName, " +
				"Address, Phone, Email, Gender, Age, InsuranceCarrier, Allergies) " +
				"VALUES ('" + username + "', '" + this.name + "', '" + this.address + "', '', '', '" + 
				this.gender + "', " + this.age + ", '" + insurance + "', '')";
		try{
			dbMgr.runUpdateQuery(sqlQuery);
		} catch(Exception e){
			LOG.severe("A SQL Error has occured while creating a patient");
			e.printStackTrace();
		} finally{
			dbMgr.closeConnection();
		}
		
		final int patientId = this.readPatientID();
		this.id = patientId;
		LOG.info("A new patient was created successfully.");
	}
	
	/**
	 * readUser overload
	 * @param patient
	 * @return patient */
	public Patient readPatient(){
		final DatabaseManager dbMgr = new DatabaseManager();
		final String sqlQuery = "SELECT * FROM patient WHERE PatientID = " + this.id;
		ResultSet rs = null;
		Patient patient = new Patient("");
		try{
			rs = dbMgr.runReadQuery(sqlQuery);
			final boolean hasRow = rs.first();
			if (hasRow){
				final String name = rs.getString("PatientName");
				final String address = rs.getString("Address");
				final String phone = rs.getString("Phone");
				final String email = rs.getString("Email");
				final String gender = rs.getString("Gender");
				final int age = rs.getInt("Age");
				final String insurance = rs.getString("InsuranceCarrier");
				final String allergy = rs.getString("Allergies");
				final insuranceCarrier carrier = this.readInsuranceFromString(insurance);
				patient.setId(id);
				patient.setName(name);
				patient.setAddress(address);
				patient.setPhone(phone);
				patient.setEmail(email);
				patient.setGender(gender);
				patient.setAge(age);
				patient.setInsuranceCarrier(carrier);
				patient.setAllergies(allergy);
			}
		} catch(Exception e){
			LOG.severe("A SQL Error occurred while reading patient info");
			e.printStackTrace();
		} finally{
			dbMgr.closeConnection(rs);
		}
		
		LOG.info("Patient info was read successfully");
		return patient;
	}
	
	/**
	 * readUser overload
	 * @param username
	 * @param name
	 * @return patient */
	public Patient lookupPatient(String username){
		final Patient patient = new Patient(name);
		final DatabaseManager dbMgr = new DatabaseManager();
		final String sqlQuery = "SELECT * FROM patient WHERE Username = '" + username + "'";
		ResultSet rs = null;

		try{
			rs = dbMgr.runReadQuery(sqlQuery);
			final boolean hasRow = rs.first();
			if (hasRow){
				final int id = rs.getInt("PatientID");
				final String address = rs.getString("Address");
				final String phone = rs.getString("Phone");
				final String email = rs.getString("Email");
				final String gender = rs.getString("Gender");
				final int age = rs.getInt("Age");
				final String insurance = rs.getString("InsuranceCarrier");
				final String allergy = rs.getString("Allergies");
				final insuranceCarrier carrier = this.readInsuranceFromString(insurance);
				patient.setId(id);
				patient.setAddress(address);
				patient.setPhone(phone);
				patient.setEmail(email);
				patient.setGender(gender);
				patient.setAge(age);
				patient.setInsuranceCarrier(carrier);
				patient.setAllergies(allergy);
			}
		} catch(Exception e){
			LOG.severe("A SQL Error occurred while reading patient info");
			e.printStackTrace();
		} finally{
			dbMgr.closeConnection(rs);
		}
		
		LOG.info("Patient info was read successfully");
		return patient;
	}
	
	/**
	 * updateUser overload
	 * @param patient
	 */
	public void updatePatient(){
		final insuranceCarrier insurance = this.getInsuranceCarrier();
		final String carrier = insurance.toString();
		
		final DatabaseManager dbMgr = new DatabaseManager();
		final String sqlQuery = "UPDATE patient SET Username = '" 
		        + this.getUsername() + "', PatientName = '" + this.name + "', Address = '" + this.address + 
		        "', Phone = '" + this.phone + "', Email = '" + this.email + "', Gender = '" + this.gender + 
		        "', Age = " + this.age + ", InsuranceCarrier = '" + carrier + 
		        "', Allergies = '' WHERE PatientID = " + this.id;
		
		try{
			dbMgr.runUpdateQuery(sqlQuery);
		} catch(Exception e){
			LOG.severe("A SQL Error ocurred while updating a patient");
			e.printStackTrace();
		} finally{
			dbMgr.closeConnection();
		}
		
		LOG.info("Patient succesfully updated");
	}
	
	/**
	 * deleteUser overload
	 * @param patient
	 */
	public void deletePatient(){
		final DatabaseManager dbMgr = new DatabaseManager();
		final String sqlQuery = "DELETE FROM patient WHERE PatientID = " + this.id;
		
		try{
			dbMgr.runUpdateQuery(sqlQuery);
		} catch(Exception e){
			LOG.severe("A SQL Error occurred while deleting patient");
			e.printStackTrace();
		} finally{
			dbMgr.closeConnection();
		}
		
		LOG.info("Patient was succesfully deleted");
	}
	
	/**
	 * Method readPatientID.
	 * @param patient Patient
	 * @return int
	 */
	public int readPatientID(){
		int id = 0;
		final String username = this.getUsername();
		final DatabaseManager dbMgr = new DatabaseManager();
		final String sqlQuery = "SELECT PatientID FROM patient WHERE Username = '" 
			+ username + "' AND PatientName = '" + this.name + "'";

		try{
			final ResultSet rs = dbMgr.runReadQuery(sqlQuery);
			rs.first();
			id = rs.getInt("PatientID");
		} catch(Exception e){
			LOG.severe("A SQL Error occurred while getting a patient id");
			e.printStackTrace();
		} finally{
			dbMgr.closeConnection();
		}
		LOG.info("PatientID successfully read");
		return id;
	}
	
	/**
	 * insuranceCarrier enum
	 */
	public enum insuranceCarrier{
		NONE, GOOD, BETTER, BEST 
	}
	
	/**
	 * 
	 * @param insurance
	 * @return provider
	 */
	public insuranceCarrier readInsuranceFromString(String insurance){
		insuranceCarrier provider = insuranceCarrier.NONE;
		if (insurance == "GOOD"){
			provider = insuranceCarrier.GOOD;
		}
		else if (insurance == "BETTER"){
			provider = insuranceCarrier.BETTER;
		}
		else if (insurance == "BEST"){
			provider = insuranceCarrier.BEST;
		}
		return provider;
	}
	
}
